<?php
/**
 * (logic)
 */
namespace App\Logic\MonthlyReport;

use App\Models\Basics\AmazonCountry;
use App\Models\Basics\ExchangeRate;
use App\Models\Delivery\FBADelivery;
use App\Models\Delivery\FBADeliveryLogistics;
use App\Models\CustomerDelivery\CustomerDelivery;
use App\Models\CustomerDelivery\CustomerDeliveryLogistics;
use App\Models\MonthlyReport\Tmp\TmpPSales;
use App\Models\OverSeasIn\Delivery as OSDelivery;
use App\Models\OverSeasIn\DeliveryLogistics as OSDeliveryLogistics;
use App\Models\OverSeasOut\FBADelivery as OSFBADelivery;
use App\Models\OverSeasOut\FBADeliveryLogistics as OSFBADeliveryLogistics;
use App\Models\OverSeasOut\RemovaleDelivery;
use App\Models\OverSeasOut\RemovaleDeliveryLogistics;
use App\Models\Product\ProductPacking;
use Illuminate\Support\Facades\DB;
class CheckLogisticsAvgPrice
{
    public static function exe($func)
    {
        try{
            DB::beginTransaction();
            self::{$func}();
            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
        }
    }

    /**
     * 4.新版小包发货出仓
     * 平均物流费
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPriceCustomerPlacing(){
        $orderIds = TmpPSales::query()
            ->where('type','Order')
            ->whereNotNull('sku')
            ->whereIn('country',['AU','AE','MX','BR'])
            ->groupBy('order_id')
            ->pluck('order_id');
        $existPs = [];
        $pds = CustomerDelivery::with('detail')
            ->whereIn('order_no',$orderIds)
            ->where('delivery_type',3)
            ->where('logistics_status',2)
            ->orderBy('delivered_at','ASC')
            ->get();
        foreach ($pds as $pd){
            $pdl = CustomerDeliveryLogistics::query()
                ->where('delivery_no',$pd->delivery_no)
                ->first();
            if(!$pdl) {
                $pd->logistics_check_status = 1;//未找到运费单
                $pd->save();
                continue;
            }
            $sumWeight = 0;
            $flagWeight = false;
            foreach ($pd->detail as $_pdd){
                if(!array_key_exists($_pdd->psku_id,$existPs)){
                    $existPs[$_pdd->psku_id] = ProductPacking::getShipWeight($_pdd->psku_id);
                }
                $oneWeight = $existPs[$_pdd->psku_id] * $_pdd->ship_num;
                if(!$oneWeight){
                    $flagWeight = true;
                    break;
                }
                $sumWeight += $oneWeight;
            }
            if($flagWeight) {
                $pd->logistics_check_status = 4;//产品中有重量为0
                $pd->save();
                continue;
            }
            if(!$sumWeight) {
                $pd->logistics_check_status = 2;//产品重量为0
                $pd->save();
                continue;
            }
            if((!$pdl->shipping_fee || ($pdl->shipping_fee == 0)) && (!$pdl->other_fee || ($pdl->other_fee == 0))) {
                $pd->logistics_check_status = 3;//费用未录入
                $pd->save();
                continue;
            }
            $pd->logistics_check_status = 0;//运费核算状态正常
            $pd->avg_price = round(((($pdl->shipping_fee ?: 0) + ($pdl->other_fee ?: 0)) / floatval($sumWeight)),3);
            $pd->save();
            foreach ($pd->detail as $pdd){
                $pdd->logistics_fee = $pd->avg_price * $existPs[$pdd->psku_id];
                $pdd->save();
            }
        }
    }

    /**
     * 3.海外仓移库-出仓
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPriceRemovaleCHUCANG(){
        $existPs = [];
        $rate = [];
        RemovaleDelivery::with('detail')
            ->where('status',4)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$rate,&$existPs){
                foreach ($ds as $d){
                    $dl = RemovaleDeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl) {
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee || ($dl->shipping_fee == 0)) && (!$dl->other_fee || ($dl->other_fee == 0)) &&
                        (!$dl->rental_fee || ($dl->rental_fee == 0)) && (!$dl->op_fee || ($dl->op_fee == 0)) &&
                        (!$dl->ex_op_fee || ($dl->ex_op_fee == 0))) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $fee = ($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0) + ($dl->rental_fee ?: 0) + ($dl->op_fee ?: 0) + ($dl->ex_op_fee ?: 0);
                    if($dl->type == 1){
                        $date = date('Y-m-01',strtotime($d->delivered_at));
                        $rateKey = $d->country_id.'_'.$date;
                        if(!array_key_exists($rateKey,$rate)){
                            if($d->country_id == 2){//CA
                                $currencyCode = 'USD';
                            }else{
                                $currencyCode = AmazonCountry::getCurrencyCodeByCountryId($d->country_id);
                            }
                            $rate[$rateKey] = ExchangeRate::getRateOddsToRMB($currencyCode,strtotime($d->delivered_at));
                        }
                        $rateOdds = $rate[$rateKey];
                        $d->avg_price = round(((($rateOdds ?: 0) * $fee) / floatval($sumWeight)),3);
                    }else{
                        $d->avg_price = round($fee / floatval($sumWeight),3);
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
            });
    }

    /**
     * 2.2.海外仓中转-出仓
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPriceCHUCANG(){
        $existPs = [];
        $rate = [];
        OSFBADelivery::with('detail')
            ->where('status',3)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$existPs,&$rate){
                foreach ($ds as $d){
                    $dl = OSFBADeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl) {
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee || ($dl->shipping_fee == 0)) && (!$dl->other_fee || ($dl->other_fee == 0)) &&
                        (!$dl->rental_fee || ($dl->rental_fee == 0)) && (!$dl->op_fee || ($dl->op_fee == 0)) &&
                        (!$dl->ex_op_fee || ($dl->ex_op_fee == 0))) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $fee = ($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0) + ($dl->rental_fee ?: 0) + ($dl->op_fee ?: 0) + ($dl->ex_op_fee ?: 0);
                    if($dl->type == 1){
                        $date = date('Y-m-01',strtotime($d->delivered_at));
                        $rateKey = $d->country_id.'_'.$date;
                        if(!array_key_exists($rateKey,$rate)){
                            if($d->country_id == 2){//CA
                                $currencyCode = 'USD';
                            }else{
                                $currencyCode = AmazonCountry::getCurrencyCodeByCountryId($d->country_id);
                            }
                            $rate[$rateKey] = ExchangeRate::getRateOddsToRMB($currencyCode,strtotime($d->delivered_at));
                        }
                        $rateOdds = $rate[$rateKey];
                        $d->avg_price = round(((($rateOdds ?: 0) * $fee) / floatval($sumWeight)),3);
                    }else{
                        $d->avg_price = round($fee / floatval($sumWeight),3);
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
            });
    }

    /**
     * 2.1.海外仓(全平台的中转,代发）-入仓
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPriceRUCANG(){
        $existPs = [];
        OSDelivery::with('detail')
            ->where('status','>=',6)//已发货或已入海外仓中转仓
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$existPs){
                foreach ($ds as $d){
                    $dl = OSDeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee || ($dl->shipping_fee == 0)) && (!$dl->other_fee || ($dl->other_fee == 0))) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->avg_price = round(((($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0)) / floatval($sumWeight)),3);
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
            });
    }

    /**
     * 1.国内仓发往FBA
     * 平均物流费 取已发货+运费已更新+未纳入统计的订单
     * 该单公斤数：所有 产品发货重量 * 发货数量 总和
     * 该单平均物流费avg_price：（该单运费+该单其它费用） / 该单公斤数
     * 该单产品物流费logistics_fee：该单平均物流费 * 产品重量
     */
    private static function _exeAvgPrice(){
        $existPs = [];
        FBADelivery::with('detail')
            ->where('status',6)//已发货
            ->where('logistics_status',2)//运费已更新
            ->where('logistics_fee_status',0)//未纳入统计
            ->orderBy('id')
            ->chunk(50, function ($ds) use (&$existPs){
                foreach ($ds as $d){
                    $dl = FBADeliveryLogistics::query()
                        ->where('delivery_no',$d->delivery_no)
                        ->first();
                    if(!$dl){
                        $d->logistics_check_status = 1;//未找到运费单
                        $d->save();
                        continue;
                    }
                    $sumWeight = 0;
                    $flagWeight = false;
                    foreach ($d->detail as $_dd){
                        if(!array_key_exists($_dd->psku_id,$existPs)){
                            $existPs[$_dd->psku_id] = ProductPacking::getShipWeight($_dd->psku_id);
                        }
                        $oneWeight = $existPs[$_dd->psku_id] * $_dd->ship_num;
                        if(!$oneWeight){
                            $flagWeight = true;
                            break;
                        }
                        $sumWeight += $oneWeight;
                    }
                    if($flagWeight) {
                        $d->logistics_check_status = 4;//产品中有重量为0
                        $d->save();
                        continue;
                    }
                    if(!$sumWeight) {
                        $d->logistics_check_status = 2;//产品重量为0
                        $d->save();
                        continue;
                    }
                    if((!$dl->shipping_fee || ($dl->shipping_fee == 0)) && (!$dl->other_fee || ($dl->other_fee == 0))) {
                        $d->logistics_check_status = 3;//费用未录入
                        $d->save();
                        continue;
                    }
                    $d->logistics_check_status = 0;//运费核算状态正常
                    $d->avg_price = round(((($dl->shipping_fee ?: 0) + ($dl->other_fee ?: 0)) / floatval($sumWeight)),3);
                    $d->save();
                    foreach ($d->detail as $dd){
                        $dd->logistics_fee = $d->avg_price * $existPs[$dd->psku_id];
                        $dd->save();
                    }
                }
        });
    }

    public static $_logisticsCheckStatus = [
        0 => '正常',
        1 => '未找到运费单',
        2 => '产品重量为0',
        3 => '费用未录入',
        4 => '产品中有重量为0',
    ];
}
